/*
 Copyright (C) 2011  Matteo Magnani, Gabriele Nunziante
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/***************************************************************************
 * CRS : Server to retrieve conversations                                  *
 ***************************************************************************
 * 
 ***************************************************************************/

import java.io.*;
import java.net.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;


public class CRConversationServer extends Thread {
	
	/* DEBUG variables */
	boolean q = false; /* true to print queries */
	boolean t = false; /* true to print tweets */
	boolean s = false; /* true to print system messages */
	
	/* Configuration variables [read from file crstoreserver.cfg] */
	private static int port; // Server listening on this port
	private static String dbServerAddress; // Database address
	private static String dbName; // Database name
	private static String dbUser; // Database user
	private static String dbPassword; // Database password
	
	//private URLConnection conn;
	private static ServerSocket serversocket;
	//static String search, server;
	
	/* DB connection */
	private static Database db;
	
	/**
	 * @param if executed for the first time, specify -c to create the index
	 */
	public static void main(String[] args) throws Exception
	{
		/* Reads configuration */
		Properties p = new Properties();
		try {
			p.load(new FileReader("crservers.cfg"));
		}
		catch (IOException ex) {
			//System.err.println("[ERR] " + ex.getMessage());
			System.err.println("Cannot open config file crservers.cfg");
			System.exit(-1);
		}
		try {
			port = Integer.parseInt(p.getProperty("conversation-port"));
		}
		catch (Exception ex) {
			//System.err.println("[ERR] " + ex.getMessage());
			System.err.println("<search-port> config info not found");
			System.exit(-1);
		}
		try {
			dbServerAddress = p.getProperty("dbServerAddress");
			if (dbServerAddress==null) throw new Exception("Could not read <dbServerAddress> config parameter");
			dbName = p.getProperty("dbName");
			if (dbName==null) throw new Exception("Could not read <dbName> config parameter");
			dbUser = p.getProperty("dbUser");
			if (dbUser==null) throw new Exception("Could not read <dbUser> config parameter");
			dbPassword = p.getProperty("dbPassword");
			if (dbPassword==null) throw new Exception("Could not read <dbPassword> config parameter");
		}
		catch (Exception ex) {
			System.err.println("[ERR] " + ex.getMessage());
			System.exit(-1);
		}
		
		/* Getting database connection */
		db = new Database(dbServerAddress, dbName, dbUser, dbPassword);
		if(!db.open()) {
			System.out.println("[ERR] DB Connection error: " + db.getError());
			System.exit(-1);
		}
		/* Opens the server socket */
		try {
			serversocket = new ServerSocket(port);
		}
		catch (Exception ex) {
			System.err.println("[ERR] " + ex.getMessage());
			System.err.println("Cannot start the server on port " + port);
			System.exit(-1);
		}
		
		System.out.println("\n* CRConversationServer waiting on port " + port);
		
		new CRConversationServer(dbServerAddress, dbName, dbUser, dbPassword);
	}
	
	public CRConversationServer(String dbServerAddress, String dbName, String dbUser, String dbPassword) throws Exception {
		while(true) {
			// Wait for connection and start thread
			try {
				Socket client = serversocket.accept();
				if (s) System.out.println("* Connection from:   " + client.getInetAddress());
				ConversationConnect c = new ConversationConnect(client, dbServerAddress, dbName, dbUser, dbPassword);
			} catch(Exception e) { 
				System.err.println("[CRConversationServer] [ERR]" + e.getMessage());
			}
		}        
	}
}

/*************************************************************************************************/

/* Class to manage a client connection */
class ConversationConnect extends Thread 
{	
	/* DEBUG variables */
	boolean q = false; /* true to print queries */
	boolean t = false; /* true to print tweets */
	boolean s = false; /* true to print system messages */	
	
	/*  */
	URLConnection conn;
	private Socket client = null;
	BufferedReader in = null;
	PrintStream out = null;
	Database db;
	
	public ConversationConnect(Socket clientSocket, String dbServerAddress, String dbName, String dbUser, String dbPassword) {		
		this.client = clientSocket;
		
		try {
			/* input/output */
			in = new BufferedReader(new InputStreamReader(client.getInputStream()));
			out = new PrintStream(client.getOutputStream(), true);
			/* Getting database connection */
			db = new Database(dbServerAddress, dbName, dbUser, dbPassword);
			if(!db.open()) {
				System.out.println("[ERR] DB Connection error: " + db.getError());
				System.exit(-1);
			}
		}
		catch (Exception ex) {
			try { client.close(); }
			catch (Exception e) { System.out.println(e.getMessage());}
			return;
		}
		this.start();
	}
	
	public void run() {
		try {
			//if (s) System.out.println("* Processing connection from " + client.getInetAddress());
			String id = in.readLine();
			String res = search(id);
			out.println(res);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			db.disconnect();
			out.close();
			in.close();
			client.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * @param id Identifier of the first tweet in the conversation
	 * @return  
	 */
	public String search(String id) throws SQLException {		
		String res = "";
		
			ResultSet rs2 = db.executeQuery("SELECT * FROM tweet join user on tweet.id_user = user.id WHERE tweet.origin='"+id+"' order by time");
			
			while( rs2!=null && rs2.next() ) {
				res = res + rs2.getString("id") + "\t" + rs2.getString("time") + "\t" + rs2.getString("name")  + "\t" + rs2.getString("screen_name") + "\t" + rs2.getString("image") 
				+ "\t" + rs2.getString("followers") + "\t" + rs2.getString("text") + "\t" + rs2.getString("reply_to") + "\n";
			}
		return res;
	}
}
